1 using System;
2 using System.Collections.Generic;
3 using UnityEngine;
4
5 namespace ProceduralToolkit
6 {
7 /// <summary>
8 /// Mesh extensions and constructors for primitives
9 /// </summary>
10 public static partial class MeshE
11 {
12 /// <summary>
13 /// Moves mesh vertices by <paramref name="vector"/>
14 /// </summary>
15 public static void Move(this Mesh mesh, Vector3 vector)
16 {
17 if (mesh == null)
18 {
19 throw new ArgumentNullException("mesh");
20 }
21 var vertices = mesh.vertices;
22 for (int i = 0; i < vertices.Length; i++)
23 {
24 vertices[i] += vector;
25 }
26 mesh.vertices = vertices;
27 }
28
29 /// <summary>
30 /// Rotates mesh vertices by <paramref name="rotation"/>
31 /// </summary>
32 public static void Rotate(this Mesh mesh, Quaternion rotation)
33 {
34 if (mesh == null)
35 {
36 throw new ArgumentNullException("mesh");
37 }
38 var vertices = mesh.vertices;
39 var normals = mesh.normals;
40 for (int i = 0; i < vertices.Length; i++)
41 {
42 vertices[i] = rotation*vertices[i];
43 normals[i] = rotation*normals[i];
44 }
45 mesh.vertices = vertices;
46 mesh.normals = normals;
47 }
48
49 /// <summary>
50 /// Scales mesh vertices uniformly by <paramref name="scale"/>
51 /// </summary>
52 public static void Scale(this Mesh mesh, float scale)
53 {
54 if (mesh == null)
55 {
56 throw new ArgumentNullException("mesh");
57 }
58 var vertices = mesh.vertices;
59 for (int i = 0; i < vertices.Length; i++)
60 {
61 vertices[i] *= scale;
62 }
63 mesh.vertices = vertices;
64 }
65
66 /// <summary>
67 /// Scales mesh vertices non-uniformly by <paramref name="scale"/>
68 /// </summary>
69 public static void Scale(this Mesh mesh, Vector3 scale)
70 {
71 if (mesh == null)
72 {
73 throw new ArgumentNullException("mesh");
74 }
75 var vertices = mesh.vertices;
76 var normals = mesh.normals;
77 for (int i = 0; i < vertices.Length; i++)
78 {
79 vertices[i] = Vector3.Scale(vertices[i], scale);
80 normals[i] = Vector3.Scale(normals[i], scale).normalized;
81 }
82 mesh.vertices = vertices;
83 mesh.normals = normals;
84 }
85
86 /// <summary>
87 /// Paints mesh vertices with <paramref name="color"/>
88 /// </summary>
89 public static void Paint(this Mesh mesh, Color color)
90 {
91 if (mesh == null)
92 {
93 throw new ArgumentNullException("mesh");
94 }
95 var colors = new Color[mesh.vertexCount];
96 for (int i = 0; i < mesh.vertexCount; i++)
97 {
98 colors[i] = color;
99 }
100 mesh.colors = colors;
101 }
102
103 /// <summary>
104 /// Flips mesh faces
105 /// </summary>
106 public static void FlipFaces(this Mesh mesh)
107 {
108 if (mesh == null)
109 {
110 throw new ArgumentNullException("mesh");
111 }
112 mesh.FlipTriangles();
113 mesh.FlipNormals();
114 }
115
116 /// <summary>
117 /// Reverses winding order of mesh triangles
118 /// </summary>
119 public static void FlipTriangles(this Mesh mesh)
120 {
121 if (mesh == null)
122 {
123 throw new ArgumentNullException("mesh");
124 }
125 for (int i = 0; i < mesh.subMeshCount; i++)
126 {
127 var triangles = mesh.GetTriangles(i);
128 for (int j = 0; j < triangles.Length; j += 3)
129 {
130 PTUtils.Swap(ref triangles[j], ref triangles[j + 1]);
131 }
132 mesh.SetTriangles(triangles, i);
133 }
134 }
135
136 /// <summary>
137 /// Reverses direction of mesh normals
138 /// </summary>
139 public static void FlipNormals(this Mesh mesh)
140 {
141 if (mesh == null)
142 {
143 throw new ArgumentNullException("mesh");
144 }
145 var normals = mesh.normals;
146 for (int i = 0; i < normals.Length; i++)
147 {
148 normals[i] = -normals[i];
149 }
150 mesh.normals = normals;
151 }
152
153 /// <summary>
154 /// Flips UV map horizontally in selected <paramref name="channel"/>
155 /// </summary>
156 public static void FlipUVHorizontally(this Mesh mesh, int channel = 0)
157 {
158 if (mesh == null)
159 {
160 throw new ArgumentNullException("mesh");
161 }
162 var list = new List<Vector2>();
163 mesh.GetUVs(channel, list);
164 for (var i = 0; i < list.Count; i++)
165 {
166 list[i] = new Vector2(1 - list[i].x, list[i].y);
167 }
168 mesh.SetUVs(channel, list);
169 }
170
171 /// <summary>
172 /// Flips UV map vertically in selected <paramref name="channel"/>
173 /// </summary>
174 public static void FlipUVVertically(this Mesh mesh, int channel = 0)
175 {
176 if (mesh == null)
177 {
178 throw new ArgumentNullException("mesh");
179 }
180 var list = new List<Vector2>();
181 mesh.GetUVs(channel, list);
182 for (var i = 0; i < list.Count; i++)
183 {
184 list[i] = new Vector2(list[i].x, 1 - list[i].y);
185 }
186 mesh.SetUVs(channel, list);
187 }
188
189 /// <summary>
190 /// Projects vertices on a sphere with given <paramref name="radius"/> and <paramref name="center"/>, recalculates normals
191 /// </summary>
192 public static void Spherify(this Mesh mesh, float radius, Vector3 center = default(Vector3))
193 {
194 if (mesh == null)
195 {
196 throw new ArgumentNullException("mesh");
197 }
198 var vertices = mesh.vertices;
199 var normals = mesh.normals;
200 for (var i = 0; i < vertices.Length; i++)
201 {
202 normals[i] = (vertices[i] - center).normalized;
203 vertices[i] = normals[i]*radius;
204 }
205 mesh.vertices = vertices;
206 mesh.normals = normals;
207 }
208 }
209 }